
# include "dfxFile_Win32.h"
# include "dfxLog.h"

namespace DFX
{
    File_Win32::File_Win32()
        : mMapFile(INVALID_HANDLE_VALUE), mMapHandle(INVALID_HANDLE_VALUE)
    {
    }

    File_Win32::~File_Win32()
    {
        Close();
    }

    DFXRESULT File_Win32::Open(const String &fileName)
    {
        mFileName = fileName;

        mMapFile = ::CreateFile(mFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);

        if (mMapFile == INVALID_HANDLE_VALUE)
        {
            DFX_ERROR( "Unable to open file: %s", mFileName.c_str());
            return DFX_OPENFAILED;
        }

        mMapHandle = CreateFileMapping(mMapFile, NULL, PAGE_READONLY, 0, 0, NULL);

        if (mMapHandle == INVALID_HANDLE_VALUE)
        {
            DFX_ERROR( "Unable to create file mapping for: %s", mFileName.c_str());
            Close();

            return DFX_OPENFAILED;
        }

        mData = (UInt8*)MapViewOfFile(mMapHandle, FILE_MAP_READ, 0, 0, 0);

        if (!mData)
        {
            DFX_ERROR( "Unable to map file for: %s", mFileName.c_str());
            Close();

            return DFX_OPENFAILED;
        }

        DWORD sizeLow = 0, sizeHigh = 0;

        sizeLow = GetFileSize(mMapFile, &sizeHigh);
        mSize = ((UInt64)sizeHigh << 32) | (UInt64)sizeLow;

        return DFX_SUCCESS;
    }

    DFXRESULT File_Win32::Close()
    {
        if (mData)
            UnmapViewOfFile(mData);

        if (mMapHandle)
            CloseHandle(mMapHandle);

        if (mMapFile)
            CloseHandle(mMapFile);

        mData = NULL;
        mMapHandle = NULL;
        mMapFile = NULL;

        return DFX_SUCCESS;
    }
}